home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
gamesrc
/
bg_src
/
bg_user2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-07
|
12KB
|
361 lines
/*
*
* B G _ U S E R 2 . C
* BG.EXE user interaction file, the second of two,
* this version 30th May 1992.
*
*/
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include "bg.h"
#include "mousy.h"
/***************************************************************************/
char User_Selects_Move (Dice_t* Dice, /* The dice the user threw */
Layout_t User_Old, /* Users current situation */
Layout_t Comp_Old, /* Computers current situation */
Transit_t* User_Tr, /* How the user moved */
Transit_t* Comp_Tr, /* Computers new situation */
Player_t Player) /* The User */
/*
PURPOSE: To get the user to move the pieces.
NOTES: 1) If an error is made or the user hits ESCAPE then we restart
the whole process, from moving the very first piece.
2) We return F10_KEY if the user wants to abandon the game.
*/
{
Dice_t Pool ; /* Local copy of input dice */
short Start,End ; /* Points selected by the user */
ushort Dice_Used ; /* Index of dice used (0..3) */
short N_Ends ; /* N legal endps poss from start selected */
short Ends [MAX_MOVES] ; /* List of endps possible */
short D_I_List [MAX_MOVES] ; /* List of indices into dice pool */
short End_Index ; /* Index into above two lists */
Transit_t Loc_User ; /* Local copies of input layouts transformed... */
Transit_t Loc_Comp ; /* ...gradually to output transits */
short Moves_Made ; /* Moves done so far */
short Moves_To_Make ; /* User MUST make this number of moves */
boolean Moved ;
char Key ;
Init_Human_Vars (&Moves_Made,&Pool,Dice, &Loc_User,&Loc_Comp,
User_Old,Comp_Old) ;
/* Get the computer to tell us how many moves to make */
Select_Best_Move (Dice,User_Old,Comp_Old,User_Tr,
Comp_Tr,Player,Legalest) ;
Moves_To_Make = User_Tr->N_Moves ;
if (Moves_To_Make == 0) {
/* You are totally blocked */
Pool.N_Vals = 0 ;
Show_Dice_List (&Pool) ;
if (Player == WHITE_PLAYER) {
Print_Message (W_NOGO_MSG) ;
} else {
Print_Message (B_NOGO_MSG) ;
}
Seconds_Delay (3) ;
Clear_Help_Line () ;
return (NUL) ; /* No keys hit by the user */
}
while ((Moves_Made < Moves_To_Make) &&
(Won(Loc_User.Layout,Loc_Comp.Layout)) == NO_WIN) {
Show_Dice_List (&Pool) ;
Moved = FALSE ;
Print_Message (SEL_STA_MSG) ;
Start = Get_User_Point_Choice (&Key,Player,OUT_ARROW_SHP) ;
if (Key == F10_KEY) {
return (F10_KEY) ;
} else if (Key == F9_KEY) {
User_Error_Exit () ;
}
if (Key != ESC_KEY) {
N_Ends = Legal_Start (&Loc_User,&Loc_Comp, /* Situation now */
&Pool, /* Dice to use */
Start, /* Start point */
Ends,D_I_List); /* List of possibles */
if (N_Ends > 0) {
Print_Message (SEL_END_MSG) ;
End = Get_User_Point_Choice (&Key,Player,IN_ARROW_SHP) ;
if (Key == F10_KEY) {
return (F10_KEY) ;
}
if (Key != ESC_KEY) {
End_Index = Legal_End (End,Ends,N_Ends) ;
if (End_Index != NOT_VALID_END) {
Dice_Used = D_I_List [End_Index] ;
Execute_Move ((char)Start,
Pool.Values[Dice_Used],
&Loc_User,&Loc_Comp) ;
Deplete_Dice_Pool (&Pool,Dice_Used) ;
Show_Dice_List (&Pool) ;
Update_User_Move (Loc_User.Layout,
Loc_Comp.Layout,
Player) ;
Moves_Made++ ;
#if DRODBAR
Show_Threat (Loc_User.Layout,Loc_Comp.Layout,End) ;
#endif
Moved = TRUE ; /* Assume he wants to do it */
if (Moves_Made == Moves_To_Make) {
Print_Message (CLK_GO_MSG) ;
(void)Get_User_Point_Choice (&Key,Player,QUESTION_SHP) ;
if (Key == F10_KEY) {
return (Key) ;
} else if (Key == ESC_KEY) {
Moved = FALSE ;
}
}
} else {
Print_Message (CANT_END_MSG) ;
Seconds_Delay(2) ;
}
}
} else {
Print_Message (CANT_START_MSG) ;
Seconds_Delay(1) ;
}
}
if (!Moved) {
/* The user has to start again, from scratch
Copy_Dice (&Pool,Dice) ;
Init_Transit (&Loc_User,User_Old) ;
Init_Transit (&Loc_Comp,Comp_Old) ;
Moves_Made = 0 ; */
Init_Human_Vars (&Moves_Made,&Pool,Dice, &Loc_User,&Loc_Comp,
User_Old,Comp_Old) ;
Update_User_Move (Loc_User.Layout,Loc_Comp.Layout,Player) ;
}
Clear_Help_Line () ;
} /* end of while () */
Copy_Transit (User_Tr,&Loc_User) ;
Copy_Transit (Comp_Tr,&Loc_Comp) ;
/* Show an empty dice list */
Pool.N_Vals = 0 ;
Show_Dice_List (&Pool) ;
return (NUL) ; /* No keys hit */
}
/***************************************************************************/
short Get_User_Point_Choice (char* Key, Player_t Player, short Shape_Code)
/*
PURPOSE: To get the user to select a point or to hit the escape key.
If the user hits a key then we return with Key set, else
we return the point selected by the user (using mouse or keyboard).
*/
{
short User_Input,Mx,My,G_Row,G_Col,Hot_X,Hot_Y ;
if (Shape_Code == NORMAL_SHP) {
Hot_X = 0 ;
Hot_Y = 0 ;
} else {
Hot_X = 7 ;
Hot_Y = 7 ;
}
Show_Mouse_Cursor () ;
Set_Cursor_Shape (Shape_Code,Hot_X,Hot_Y) ;
(*Key) = NUL ;
do {
User_Input = Get_Mouse_Or_Key (&Mx,&My) ;
if (User_Input & KEY_BIT) {
if ((User_Input & CHAR_MASK) == ESC_KEY) {
Hide_Mouse_Cursor () ;
(*Key) = ESC_KEY ;
return (0) ;
}
} else if (User_Input & FUN_BIT) {
if ((User_Input & CHAR_MASK) == F10_KEY) {
Hide_Mouse_Cursor () ;
(*Key) = F10_KEY ;
return (0) ;
}
if ((User_Input & CHAR_MASK) == F9_KEY) {
Hide_Mouse_Cursor () ;
(*Key) = F9_KEY ;
return (0) ;
}
}
} while (!(User_Input & (LEFT_BIT | RIGHT_BIT))) ;
Hide_Mouse_Cursor () ;
/* Mx, My now contain the mouse coords */
if (Pixel_To_Grid (&G_Col,&G_Row,Mx,My)) {
return (Grid_To_Point (G_Col,G_Row,Player)) ;
} else {
return (0) ;
}
}
/***************************************************************************/
short Legal_Start (Transit_t* Me, Transit_t* Him, /* These are the... */
Dice_t* Dice, short Point, /* ...inputs. */
short End_Points[MAX_MOVES], /* List of end points possible */
short D_I_List[MAX_MOVES]) /* Dice used for the end point */
/*
PURPOSE: Given the inputs we return the number of moves we can make with
this dice along with with End_Points and D_I_List.
*/
{
short epi,d ; /* End Point Index */
epi = 0 ;
for (d = 0 ; d < Dice->N_Vals ; d++) {
if (Can_Move (Point,Dice->Values[d],Me->Layout,Him->Layout)) {
End_Points[epi] = Point+Dice->Values[d] ;
if (End_Points[epi] > HOME_I) {
End_Points[epi] = HOME_I ;
}
D_I_List [epi] = d ;
epi++ ;
}
}
return (epi) ;
}
/***************************************************************************/
short Legal_End (short Point, short List[MAX_MOVES], short N_Ends)
/*
PURPOSE: The user wants to move to Point, if it's in the list we return
it's index, else we return NOT_VALID_END
*/
{
short p ;
p = 0 ;
while (p < N_Ends) {
if (Point == List[p]) {
return (p) ;
}
p++ ;
}
return (NOT_VALID_END) ;
}
/***************************************************************************/
void Update_User_Move (Layout_t User, Layout_t Comp, Player_t Player)
/*
PURPOSE: To redraw the board showing the users positions, whether he
is white or black.
*/
{
if (Player == BLACK_PLAYER) {
Draw_Board_Quick (User,Comp) ;
} else {
Draw_Board_Quick (Comp,User) ;
}
}
/***************************************************************************/
#if DRODBAR
void Show_Threat (Layout_t Me, Layout_t Him, short Point)
/*
PURPOSE: To print the threat of him to me at this point.
*/
{
short Threat ;
Side_Text (THREAT_ROW,0,"THREAT: ",WHITE) ;
Threat = Get_Probs (Me,Him,Point,FALSE) ;
Side_Number (THREAT_ROW,9,Threat,3,WHITE) ;
}
#endif
/***************************************************************************/
void Init_Human_Vars (short* Moves_Made, Dice_t* Pool, Dice_t* Dice,
Transit_t* Loc_User, Transit_t* Loc_Comp,
Layout_t User_Old, Layout_t Comp_Old)
/*
PURPOSE: To prepare the above vars for a new user move, starting from scratch.
*/
{
(*Moves_Made) = 0 ; /* He has not yet moved */
Copy_Dice (Pool,Dice) ; /* So he has all initial dice values */
Init_Transit (Loc_User,User_Old) ; /* Init the transits from... */
Init_Transit (Loc_Comp,Comp_Old) ; /* ...what he starts with. */
}
/***************************************************************************/
void User_Error_Exit (void)
/*
PURPOSE: To let the user send a message about something he has noticed
has gone wrong before abandoning the game. The error message is the
last thing typed in the file BG??.REC
*/
{
extern char Globerr [GERR_LEN] ;
short i ;
int ch ;
Clear_Help_Line () ;
Help_Text (0,"TYPE ERROR DESCRIPTION:",WHITE) ;
i = 0 ;
Globerr [i] = NUL ;
while ((ch = getch ()) != ENTER_KEY) {
if ((ch == BACK_KEY) && (i > 0)) {
i-- ;
Globerr[i] = NUL ;
} else if (i < (GERR_LEN-1)) {
Globerr[i] = (char)ch ;
printf ("%c",ch) ;
i++ ;
Globerr[i] = NUL ;
}
}
Error_Exit ("USER HIT F9") ;
}
/***************************************************************************/
short Key_And_Delay (short Seconds)
/*
PURPOSE: To wait Seconds or until a key is hit. We return the key hit
or zero if we timed out first.
*/
{
char Key_0 ;
short Key_Code ;
time_t Now,Then ;
(void)time (&Then) ;
do {
if (kbhit()) {
Key_0 = (char)getch () ;
if (Key_0 == FUN_PREFIX) {
Key_Code = FUN_BIT | getch () ;
} else {
Key_Code = KEY_BIT | Key_0 ;
}
return (Key_Code) ;
}
(void)time(&Now) ;
} while ((Now - Then) < Seconds) ;
return (0) ;
}
/***************************************************************************/